unit person_controller;

{$mode objfpc}{$H+}

interface

uses
  SysUtils,
  Classes,
  httpdefs,
  fpHTTP,
  fpWeb,
  person,
  hadesession,
  templateutils;

type

  { TmodPerson }

  TmodPerson = class(TFPWebModule)
    procedure contactdetailsAfterResponse(Sender: TObject; AResponse: TResponse);
    procedure contactdetailsBeforeRequest(Sender: TObject; ARequest: TRequest);
    procedure contactdetailsRequest(Sender: TObject; ARequest: TRequest;
      AResponse: TResponse; var Handled: boolean);
    procedure DataModuleAfterResponse(Sender: TObject; AResponse: TResponse);
    procedure DataModuleBeforeRequest(Sender: TObject; ARequest: TRequest);
    procedure DataModuleCreate(Sender: TObject);
    procedure indexAfterResponse(Sender: TObject; AResponse: TResponse);
    procedure indexBeforeRequest(Sender: TObject; ARequest: TRequest);
    procedure indexRequest(Sender: TObject; ARequest: TRequest;
      AResponse: TResponse; var Handled: boolean);
    procedure officedetailsAfterResponse(Sender: TObject; AResponse: TResponse);
    procedure officedetailsBeforeRequest(Sender: TObject; ARequest: TRequest);
    procedure officedetailsRequest(Sender: TObject; ARequest: TRequest;
      AResponse: TResponse; var Handled: boolean);
  private
    fPersonList: TPersonList;
    fPerson: TPerson;
    template: TPersonTemplate;
    maintemplate: TMainTemplate;
    fOfficeDetailsTemplate: TOfficeDetailsTemplate;
    fContactDetailsTemplate: TContactDetailsTemplate;
    procedure checkInput(const oidInput: string; out oid: integer);
  public

  end;

  EInvalidOIDParameter = class(Exception)
  end;

var
  modPerson: TmodPerson;

implementation

uses
  config,
  fpfcgi,
  hadecriteria;

{$R *.lfm}

{ TmodPerson }

procedure TmodPerson.contactdetailsAfterResponse(Sender: TObject; AResponse: TResponse);
begin
  AResponse.Contents.Add(maintemplate.getTemplate.GetContent);
  AResponse.SendContent;
  FreeAndNil(fContactDetailsTemplate);
  FreeAndNil(fperson);
end;

procedure TmodPerson.contactdetailsBeforeRequest(Sender: TObject; ARequest: TRequest);
begin
  fContactDetailsTemplate := TContactDetailsTemplate.Create;
  maintemplate.ContentTemplate := fContactDetailsTemplate;
  maintemplate.PageTitle := 'Person::Contact details';
end;

procedure TmodPerson.contactdetailsRequest(Sender: TObject; ARequest: TRequest;
  AResponse: TResponse; var Handled: boolean);
var
  ownerOID: integer;
  iloop: integer;
  tmp: string;
  lsession:THadeSession;
  ACriteria: THadeCriteria;
begin
  checkInput(ARequest.QueryFields.Values['personoid'], ownerOID);
  fContactDetailsTemplate.PrevLink := ARequest.QueryFields.Values['prevurl'];
  fperson := TPerson.Create(ownerOID);
  lsession:=GHadeSessionFactory.CreateSession('test');
  lsession.Read(fPerson);

  ACriteria:=THadeCriteria.Create();
  ACriteria.Equal('oid',fperson.oid.IntegerOID);
  lsession.Read(fperson.Contact,ACriteria);//read contactList

  if fPerson.Contact.Count <= 0 then
  begin
    AResponse.Contents.Add('No Data Available.');
    AResponse.SendContent;
    Handled := True;
  end;
  fContactDetailsTemplate.person := fPerson.FullName;
  fContactDetailsTemplate.ColumnName.Add('<td>NO</td>');
  fContactDetailsTemplate.ColumnName.Add('<td>OID</td>');
  fContactDetailsTemplate.ColumnName.Add('<td>Contact_Name</td>');
  fContactDetailsTemplate.ColumnName.Add('<td>Address</td>');
  fContactDetailsTemplate.ColumnName.Add('<td>Email</td>');
  fContactDetailsTemplate.ColumnName.Add('<td>Phone</td>');


  for iloop := 0 to pred(fperson.Contact.Count) do
  begin
    tmp := '';
    tmp := tmp + '<td>' + IntToStr(Succ(iloop)) + '</td>';
    tmp := tmp + '<td>' + fperson.Contact.Items[iloop].OID.StringOID + '</td>';
    tmp := tmp + '<td>' + fperson.Contact.Items[iloop].ContactName + '</td>';
    tmp := tmp + '<td>' + fperson.Contact.Items[iloop].Address + '</td>';
    tmp := tmp + '<td>' + fperson.Contact.Items[iloop].Email + '</td>';
    tmp := tmp + '<td>' + fperson.Contact.Items[iloop].Phone + '</td>';
    fContactDetailsTemplate.Values.Add('<tr>' + tmp + '</tr>');
  end;

  handled := True;
end;

procedure TmodPerson.DataModuleAfterResponse(Sender: TObject; AResponse: TResponse);
begin
  FreeAndNil(maintemplate);
end;

procedure TmodPerson.DataModuleBeforeRequest(Sender: TObject; ARequest: TRequest);
begin
  maintemplate := TMainTemplate.Create;
end;

procedure TmodPerson.DataModuleCreate(Sender: TObject);
begin
  Actions.ActionByName('index').Default := True;
  ActionVar := 'action';
end;

procedure TmodPerson.indexAfterResponse(Sender: TObject; AResponse: TResponse);
begin
  FreeAndNil(fPersonList);
  //kick the result out!
  AResponse.Contents.Add(maintemplate.getTemplate.GetContent);
  AResponse.SendContent;
  FreeAndNil(template);
end;

procedure TmodPerson.indexBeforeRequest(Sender: TObject; ARequest: TRequest);
begin
  template := TPersonTemplate.Create;
  maintemplate.ContentTemplate := template;
  fPersonList := TPersonList.Create;
  template.PrevLink := TMyURLHelper.BaseUrl();
  maintemplate.Title := 'Table of Person';
  maintemplate.PageTitle := 'Person';
end;

procedure TmodPerson.indexRequest(Sender: TObject; ARequest: TRequest;
  AResponse: TResponse; var Handled: boolean);
var
  iloop: integer;
  tmp: string;
  contactlink: string;
  officeLink: string;
  lsession:THadeSession;
begin
  lsession:=GHadeSessionFactory.CreateSession('test');
  lsession.read(fPersonList);
  if fPersonList.Count <= 0 then
  begin
    AResponse.Contents.Add('No Data Available.');
    AResponse.SendContent;
    Handled := True;
  end;
  template.RecCount := fPersonList.Count;
  template.ColumnName.Add('<td>NO</td>');
  template.ColumnName.Add('<td>OID</td>');
  template.ColumnName.Add('<td>First_Name</td>');
  template.ColumnName.Add('<td>Last_Name</td>');
  template.ColumnName.Add('<td>Age</td>');
  template.ColumnName.Add('<td>Contact</td>');
  template.ColumnName.Add('<td>Office</td>');

  for iloop := 0 to pred(fPersonList.Count) do
  begin
    tmp := '';
    tmp := tmp + '<td>' + IntToStr(Succ(iloop)) + '</td>';
    tmp := tmp + '<td>' + fPersonList.Items[iloop].OID.StringOID + '</td>';
    tmp := tmp + '<td>' + fPersonList.Items[iloop].First_Name + '</td>';
    tmp := tmp + '<td>' + fPersonList.Items[iloop].Last_Name + '</td>';
    tmp := tmp + '<td>' + IntToStr(fPersonList.Items[iloop].Age) + '</td>';

    contactlink := TMyURLHelper.SiteUrl('person', 'contactdetails', self.ActionVar) +
      '&personoid=' + fPersonList.Items[iloop].OID.StringOID +
      '&prevurl=' + TMyUrlHelper.SiteUrl('person', 'index');
    tmp := tmp + '<td><a href="' + contactLink + '">Contact</a></td>';

    officeLink := TMyURLHelper.SiteUrl('person', 'officedetails') +
      '&personoid=' + fPersonList.Items[iloop].OID.StringOID +
      '&prevurl=' + TMyUrlHelper.SiteUrl('person', 'index', self.ActionVar);
    tmp := tmp + '<td><a href="' + officeLink + '">Office</a></td>';

    template.Values.Add('<tr>' + tmp + '</tr>');
  end;
  handled := True;
end;

procedure TmodPerson.officedetailsAfterResponse(Sender: TObject; AResponse: TResponse);
begin
  mainTemplate.ContentTemplate := fOfficeDetailsTemplate;//inject into contenttemplate
  AResponse.Contents.Add(maintemplate.getTemplate.getContent);
  AResponse.SendContent;
  FreeAndNil(fPerson);
  FreeAndNil(fOfficeDetailsTemplate);
end;

procedure TmodPerson.officedetailsBeforeRequest(Sender: TObject; ARequest: TRequest);
begin
  fOfficeDetailsTemplate := TOfficeDetailsTemplate.Create;
  maintemplate.PageTitle := 'Person::Office Details';
end;

procedure TmodPerson.officedetailsRequest(Sender: TObject; ARequest: TRequest;
  AResponse: TResponse; var Handled: boolean);
var
  ownerOID: integer;
  lsession:THadeSession;
begin
  checkInput(Request.QueryFields.Values['personoid'], ownerOID);
  fOfficeDetailsTemplate.PrevLink := Request.QueryFields.Values['prevurl'];
  fPerson := TPerson.Create(ownerOID);
  lsession:=GHadeSessionFactory.CreateSession('test');
  lsession.Read(fPerson);

  lsession.Read(fPerson.Office);//read the office
  maintemplate.Title := 'Office Details of ' + fPerson.FullName;
  fOfficeDetailsTemplate.OID := fPerson.Office.OID.StringOID;
  fOfficeDetailsTemplate.OfficeName := fPerson.Office.OfficeName;
  fOfficeDetailsTemplate.OfficeAddress := fPerson.Office.OfficeAddress;
  fOfficeDetailsTemplate.Web := fPerson.Office.web;
  fOfficeDetailsTemplate.Email := fPerson.Office.Email;
  fOfficeDetailsTemplate.Phone := fPerson.Office.Phone;

  handled := True;
end;

procedure TmodPerson.checkInput(const oidInput: string; out oid: integer);
begin
  if oidInput = 'NULL' then
  begin
    raise EInvalidOIDParameter.Create('this person have no office.');
  end;

  if not TryStrToInt(oidInput, OID) then
  begin
    raise EInvalidOIDParameter.Create('oid parameter must be valid integer.');
  end;
end;

initialization
  RegisterHTTPModule('Person', TmodPerson);
end.

